#include "Channel.hpp"
#include "task.hpp"
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>

class ProcessPool
{
public:
    ProcessPool(int process_num = 5)
        :_process_num(process_num)
    {}

    int create_process(work_t work)
    {
        for (int i = 0; i < _process_num; ++i)
        {
            pid_t id = fork();
            int pipefd[2] = {0};
            int n = pipe(pipefd);
            if(n < 0)
            {
                printf("创建管道失败\n");
                return 2;
            }
            if (id == 0)
            {
                // r
                close(pipefd[1]);
                while(1)
                {
                    int task_node = 0;
                    ssize_t n = read(pipefd[0], &task_node, sizeof(task_node));
                    cout << "接收一个信息" << task_node << endl;
                    task[task_node](1);
                    sleep(1);
                }
                exit(0);
            }
            // w
            close(pipefd[0]);
            string name = "process " + to_string(i);
            _Channels.push_back(Channel(name, pipefd[1], id));
        }
        return 0;
    }

    void Debug()
    {
        for(auto& cl : _Channels)
        {
            cl.Debug();
        }
    }

    Channel& ChooseChannel()
    {
        static int i = 0;
        Channel& channel = _Channels[i++];
        i %= _process_num;
        return channel;
    }

    ~ProcessPool()
    {}

private:
    int _process_num;
    vector<Channel> _Channels;
};

int Main(int argc, char *argvs[])
{
    if (argc != 2)
    {
        cout << "参数个数错误" << endl;
        return 1;
    }

    int process_num = stoi(argvs[1]);
    
    if (process_num <= 0)
    {
        cout << "参数设置错误" << endl;
        return 2;
    }
    
    srand((unsigned int)time(nullptr));
    ProcessPool* processpool_ptr = new ProcessPool(process_num);
    work_t work = Work;
    processpool_ptr->create_process(work);
    processpool_ptr->Debug();

    //控制子进程执行任务
    while(1)
    {
        Channel channel = processpool_ptr->ChooseChannel();
        int task_node = getTaskNode();
        cout << "写入一个信息: " << task_node << endl;
        write(channel.getwfd(), &task_node, sizeof(task_node));
        sleep(1);
    }

    sleep(100);
    delete processpool_ptr;
    return 0;
}

//./processpool 5
int main(int argc, char *argvs[])
{
    return Main(argc, argvs);   
}